require'lasync'
require'socket'

t=socket.tcp()
t:settimeout(0.1)
dispatch={}
uri = 'GET / HTTP/1.1\r\nhost: www.yahoo.com\r\n\r\n'
timer={}
t:connect('www.yahoo.com',80)
libevent = lasync.handle()
--e = libevent:event(t:getfd(), t):open(1)
--assert(e:object() == t)
a = libevent:event(-1, timer):open(10)

co_send = coroutine.create(
    function(skt, data)
        local d,e,c
        for i=1,#data do
            d,e,c = skt:send(data,i,i)
            coroutine.yield(d,e,c)
        end
        return d,e,c
    end
    )
co_receive = coroutine.create(
    function(skt)
        local data={}
        local d,e,c
        repeat
        d,e,c = skt:receive(1024)
        data[#data+1]=d  or c or ""
        coroutine.yield()
        until e~=nil
        data = table.concat(data,"")
        return data,e
    end
    )

function dispatch:readable(ev)
    assert(self == dispatch)
    local skt = ev:object()
    assert(ev:object() == t)
    if coroutine.status(co_receive) ~= "dead" then
        local e,r = coroutine.resume(co_receive, skt)
        if e and r then 
            print(r)
        end
    else
        ev:skip(lasync.EV_READ)
    end
end
j=0
function dispatch:writable(ev)
    assert(self == dispatch)
    assert(ev:object() == t)
    local skt = ev:object()
    local co,i,e,c
    if coroutine.status(co_send) ~= "dead" then
        --print("writable")
        co,i, e, c = coroutine.resume(co_send, skt, uri)
    else
        ev:skip(lasync.EV_WRITE)
    end
end

function dispatch:timeout(ev)
    assert(self == dispatch)
    local skt = ev:object()
    assert(skt == t or skt == timer)
    print(self, skt, "timeout")
    ev:settimeout(-1)
end

function dispatch:signal(ev)
    assert(self == dispatch)
    local skt = ev:object()
    assert(skt == t or skt == timer)
    print(self, skt, "signal")
end

--assert(a:object() == timer)
libevent:loop(dispatch)
